<template>
  <div id="district_box">
    <n-input-group>
      <n-select
        v-if="componentType === 'select'"
        v-model:value="proxyAdcode"
        filterable
        :options="selectOptions"
        label-field="name"
        value-field="adcode"
        :show-arrow="false"
        placeholder="请输入关键词搜索区域"
        to="#district_box"
        style="width: 188px"
        @update:value="selectChange"
        v-bind="$attrs"
      ></n-select>
      <n-tree-select
        v-else
        v-model:value="proxyAdcode"
        filterable
        show-path
        :options="treeOptions"
        placeholder="请输入关键词搜索区域"
        label-field="name"
        key-field="adcode"
        to="#district_box"
        style="width: 188px"
        @update:value="selectChange"
        v-bind="$attrs"
      />
      <n-button
        v-if="!isWithUpdate"
        round
        style="
          width: 34px;
          --n-border: 1px solid rgba(154, 186, 255, 0.16);
          --n-color-hover: rgba(130, 151, 255, 0.19);
        "
        @click="search"
      >
        <template #icon>
          <n-icon class="icon" size="14" color="#fff" :component="SearchOutline"></n-icon>
        </template>
      </n-button>
    </n-input-group>
  </div>
</template>

<script setup lang="ts">
/**
 * @description 全国省市区县搜索，返回搜索目标的完整面包屑路径，可配置getDistrictRoutesInfo的参数，指定返回几级路由
 */
import { getDistrictGeoData, getDistrictRoutesInfo } from './districtGeo'
import { options, filterOptions, diyOptions } from './district'
import { Item } from './types'

import { SearchOutline } from '@vicons/ionicons5'

type ComponentType = 'select' | 'treeSelect'

const props = withDefaults(
  defineProps<{
    /** 受控的值, 指定省份或者城市的时候需要传入对应值, 否则无法对应初始值 */
    adcode: string
    /** 是否需要地图geoJson数据 */
    hasGeoJson?: boolean
    /** 选项更新完是否通知更新, 默认通知更新， 设置为false的话，用于点击搜索按钮更新 */
    isWithUpdate?: boolean
    /** 区域搜索组件类型 */
    componentType?: ComponentType
    /** 指定省份， 返回下属市，这个参数只用于下拉筛选模式下 */
    province?: string
    /** 与province配合指定城市， 返回下属区县，这个参数只用于下拉筛选模式下 */
    city?: string
    /** 搜索后的结果保留到几级，如只展示到市级地图，但是选择了该市下面的某个区县，则可以将level设置为3 */
    level?: number
    /** 树状状态下的选项到什么层级, 默认三级，也就是区县层次 */
    treeOptionsLevel?: number
  }>(),
  {
    hasGeoJson: false,
    isWithUpdate: true,
    componentType: 'treeSelect',
    level: 3,
    treeOptionsLevel: 3
  }
)
const emit = defineEmits<{
  (e: 'update:adcode', val: string): void
  (
    e: 'search',
    obj: {
      breadData: Item[]
      geoData: any
    }
  ): void
}>()

/** 树状组件选项 */
const treeOptions = computed(() => {
  return diyOptions(options, props.treeOptionsLevel)
})

/** 下拉框选项 */
const selectOptions = computed(() => {
  return filterOptions(options, props.province, props.city)
})

/** 面包屑数据 */
const breadCrumbsData = ref<Array<Item>>([])
/** 地图范围选项-adCode */
const proxyAdcode = computed({
  get() {
    return props.adcode
  },
  set(val: string) {
    console.log(val)

    emit('update:adcode', val)
  }
})

/** 通知更新 */
function search(res: any) {
  emit('search', {
    breadData: breadCrumbsData.value,
    geoData: res
  })
}

/**
 * @description 更新数据
 * @param init 是否为初始更新
 */
async function getData(init = false, curItem?: Item) {
  let res: any

  if (props.hasGeoJson) {
    res = await getDistrictGeoData(curItem?.adcode || proxyAdcode.value)
  }

  breadCrumbsData.value = getDistrictRoutesInfo(
    curItem?.adcode || proxyAdcode.value,
    curItem,
    props.level
  )
  console.log(
    breadCrumbsData.value,
    'breadCrumbsData.value',
    proxyAdcode.value,
    curItem,
    props.level
  )

  /** 当地图展示层级小于选中的层级时，自动更新为所能展示的最大层级 */
  proxyAdcode.value = breadCrumbsData.value[breadCrumbsData.value.length - 1].adcode

  /** 初始化的时候或者组件为同步更新的时候直接通知地图更新 */
  if (init || props.isWithUpdate) {
    search(res)
  }
}

getData(true)

function selectChange(val: string, curItem: Item) {
  getData(false, curItem)
}
</script>

<style lang="less" scoped>
// :deep(.n-button) {
//   background: rgba(133, 165, 255, 0.1);
// }
:deep(.n-base-selection) {
  border-radius: 16px;
}
// :deep(.n-base-selection .n-base-selection-label) {
//   background-color: rgba(133, 165, 255, 0.1);
// }
// :deep(.n-base-selection--focus .n-base-selection-label) {
//   background-color: rgba(130, 151, 255, 0.19) !important;
// }
// :deep(.n-base-selection__border) {
//   border-color: rgba(154, 186, 255, 0.16);
// }

// :deep(.n-tree-select-menu) {
//   background-color: #00000050 !important;
//   backdrop-filter: blur(9px);
// }

// :deep(.n-base-select-menu) {
//   background-color: #00000050 !important;
//   backdrop-filter: blur(9px);
// }
</style>
